<template>
  <div class="alloc-resource">
    <el-card
      class="box-card"
      v-for="category in roleResourceData"
      :key="category.id"
    >
      <div slot="header" class="clearfix">
        <el-checkbox
          :indeterminate="category.isIndeterminate"
          v-model="category.selected"
          @change="handleCheckAllChange(category)"
          >{{ category.name }}</el-checkbox
        >
      </div>
      <el-checkbox-group
        v-model="category.checkedResourceIds"
        @change="handleCheckedResourceChange(category)"
      >
        <el-row>
          <el-col
            :span="8"
            v-for="resource in category.resourceList"
            :key="resource.id"
          >
            <el-checkbox :label="resource.id">{{
              resource.name
            }}</el-checkbox></el-col
          >
        </el-row>
      </el-checkbox-group>
    </el-card>
    <div class="footer-btn">
      <el-button type="primary" @click="onSave()">保存</el-button>
      <el-button @click="onClear()">清空</el-button>
    </div>
  </div>
</template>
<script>
import { getRoleResource, setRoleResource } from '@/api/role'
export default {
  name: 'RoleAllocResource',
  props: {
    roleId: {
      type: [String, Number],
      required: true
    }
  },
  data () {
    return {
      roleResourceData: []
    }
  },
  created () {
    this.loadResource(this.roleId)
  },
  methods: {
    // 保存
    onSave () {
      const { roleId, roleResourceData } = this
      const resourceIdList = roleResourceData.reduce((res, category) => {
        return res.concat(category.checkedResourceIds)
      }, [])
      setRoleResource({ roleId, resourceIdList }).then((res) => {
        if (res.data.code === '000000') {
          this.$message.success('给角色分配资源成功')
          this.$router.push({ name: 'roles' })
        } else {
          this.$message.error('给角色分配资源失败')
        }
      })
    },
    // 清空
    onClear () {
      this.roleResourceData.forEach((category) => {
        category.checkedResourceIds = []
        category.selected = false
        category.isIndeterminate = false
      })
    },
    // 获取角色拥有的资源信息
    loadResource (roleId) {
      getRoleResource(roleId).then((res) => {
        if (res.data.code === '000000') {
          this.roleResourceData = res.data.data.map((category) => {
            let { id, name, resourceList, selected, sort } = category

            const checkedResourceIds = [] // 已选中的
            const allResourceIds = [] // 所有的选项
            let isIndeterminate = false // 类别是否为半选状态 显示为-号

            resourceList = resourceList?.map((resource) => {
              const { id, name, selected, url, description } = resource
              if (selected) checkedResourceIds.push(id)
              allResourceIds.push(id)
              return { id, name, selected, url, description }
            })

            isIndeterminate =
              checkedResourceIds.length > 0 &&
              checkedResourceIds.length < allResourceIds.length

            // 修正类别选中状态
            selected = checkedResourceIds.length === allResourceIds.length

            return {
              id,
              name,
              resourceList,
              selected,
              sort,
              checkedResourceIds,
              allResourceIds,
              isIndeterminate
            }
          })
        } else {
          this.$message.error('获取角色拥有的资源信息失败')
        }
      })
    },
    // 全选操作
    handleCheckAllChange (category) {
      category.checkedResourceIds = category.selected
        ? category.allResourceIds
        : []
      category.isIndeterminate = false
    },
    // change 事件
    handleCheckedResourceChange (category) {
      const checkedCount = category.checkedResourceIds.length
      const totalCount = category.allResourceIds.length
      category.selected = checkedCount === totalCount
      category.isIndeterminate = checkedCount > 0 && checkedCount < totalCount
    }
  }
}
</script>
<style scoped lang="scss">
.el-card {
  margin-top: 20px;
}
.footer-btn {
  display: flex;
  justify-content: center;
  margin-top: 20px;
}
</style>
